let _socket_util = module.exports

const serviceRegService = require('../../../service/dao/serviceReg')
const amqp_cfg = configure.get('amqp')
const im_suffix = amqp_cfg.im_suffix || ''

const SOCKET_ERROR = {
    900: '身份认证成功',
    999: 'IM系统异常',
    909: '缺少 jwt 信息',
    910: '缺少 product 信息',
    911: '信息不是一个对象',
    901: '缺少 iss',
    902: '缺少 user_id',
    903: 'iss 不存在或者已禁用',
    904: '用户不存在或者已禁用',
    905: 'jwt 验证失败',
    906: '系统检测到您已在其他地方登录，请重新登录',
    907: 'IM Server 目前只提供给IOS，Android, Web端使用',
    908: '缺少 content',
    1000: '系统推送信息'
}

const emitMessage = async (io, socket_id = '', data = {}, action = 'SystemMessage') => {
    if (!socket_id) return false
    if (_.isEmpty(data)) return false
    const uuid = helper.uuid()
    data = { ...data, id: uuid, create_at: helper.now() }
    log4js.debug('message rel: ' + JSON.stringify(data))
    io.to(socket_id).emit(action, data)
    return true
}

const messageBuilder = (code, message, to = '') => {
    return {
        from: 'SYSTEM',
        to: to,
        session_type: 1,
        message_type: code,
        content: message || SOCKET_ERROR[code] || '',
        status: 1,
    }
}

const initialize = async (io, socket, payload) => {
    let app_names = payload['app_name'].split('_')
    let user_id = payload['user_id']
    let _current_socket_type = app_names[1]
    let _current_product_type = app_names[0]

    if (app_names.length > 1) { // 客户端连接
        let _cli = await dbUtil.getRow('im_client_socket', {
            im_suffix: im_suffix,
            user_id: user_id,
            product: _current_product_type
        })

        let _user_socket = {
            android: _.get(_cli, 'socket_id_android') || '',
            ios: _.get(_cli, 'socket_id_ios') || '',
            web: _.get(_cli, 'socket_id_web') || '',
        }

        let data = {}
        data[`socket_id_${_current_socket_type}`] = socket.id

        // 已登录 -> 踢掉前一个
        if (_cli && _current_socket_type !== 'web' && !_.isEmpty(_user_socket[_current_socket_type])) {
            log4js.debug(`tick before: user_id=${user_id},app_name=${payload['app_name']},socket_id=${_user_socket[_current_socket_type]}`)
            await emitMessage(io, _user_socket[_current_socket_type], messageBuilder(906, SOCKET_ERROR[906],_user_socket[_current_socket_type]))
        }

        // 移动端互踢
        Object.keys(_user_socket).map(async item => {
            if (_current_socket_type !== 'web' && item !== 'web' && item !== _current_socket_type) {
                log4js.debug(`tick others: user_id=${payload['user_id']},client=${item},socket_id=${_user_socket[item]}`)
                await emitMessage(io, _user_socket[item], messageBuilder(906, SOCKET_ERROR[906], _user_socket[item]))
            }
        })

        _cli ?
            await M('im_client_socket').updateOne({ _id: _cli._id }, { $set: { ...data } })
            :
            await M('im_client_socket').create({
                im_suffix: im_suffix,
                user_id: user_id,
                product: _current_product_type,
                ...data,
            })

        // 发送连接成功消息
        await emitMessage(io, socket.id, messageBuilder(900,null,socket.id))

        if (_current_socket_type === 'web') {
            log4js.debug(`${socket.id} join room: ${user_id}_web`)
            socket.join(`${user_id}_web`)
        }
    } else { // 服务连接
        let _svr = await dbUtil.getRow('service_reg', { app_key: payload.app_key, im_suffix: im_suffix })

        _svr ?
            await M('service_reg').updateOne({ _id: _svr._id }, { $addToSet: { client_ids: socket.id } })
            :
            await M('service_reg').create({
                app_key: payload.app_key,
                im_suffix: im_suffix,
                app_name: payload.app_name,
                client_ids: [socket.id]
            })

        // 注册监听
        socket.on('onRegData', async (msg) => {
            log4js.debug('receive onRegData: ', JSON.stringify(msg))
            const { data, type } = msg
            if (type === 1) {
                await serviceRegService.reg(socket.jwt.app_key, data)
            } else if (type === 2) {
                await serviceRegService.unReg(socket.jwt.app_key, data)
            }
        })

        // 分发主从选举信息
        _svr = await dbUtil.getRow('service_reg', { app_key: payload.app_key, im_suffix: im_suffix })
        _svr.client_ids.map(async (_s, _i) => {
            _i === 0 ?
                await emitMessage(io, _s, messageBuilder(1000, { is_leader: true }, _s), 'LeaderSelect')
                :
                await emitMessage(io, _s, messageBuilder(1000, { is_leader: false }, _s), 'LeaderSelect')
        })

        // 发送连接成功消息
        await emitMessage(io, socket.id, messageBuilder(900, null, socket.id))
    }

    return true
}

_socket_util.SOCKET_ERROR = SOCKET_ERROR
_socket_util.emitMessage = emitMessage
_socket_util.messageBuilder = messageBuilder
_socket_util.initialize = initialize
